<?php
namespace tool;


use ZPHP\Core\Log;

class AesCode
{
    private $iv = "0988454384fedcba";//密钥偏移量IV，可自定义
    private $encryptKey = "azsqed1234567890";//AESkey，可自定义
    /**
     *解密参数
     * @param
     * @return string
     */
    public function decode($encryptStr)
    {
      $localIV = $this->iv;
      $encryptKey = $this->encryptKey;

      //Open module
      $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');

      //print "module = $module <br/>" ;

      mcrypt_generic_init($module, $encryptKey, $localIV);

      $encryptedData = base64_decode($encryptStr);
      $encryptedData = mdecrypt_generic($module, $encryptedData);

      //Close
      mcrypt_generic_deinit($module);
      mcrypt_module_close($module);
//      var_dump($encryptedData);exit;
//      $n = strpos('}',$encryptedData);
        $encryptedData = trim($encryptedData);
        $encryptedData = $this->stripPKSC7Padding($encryptedData);
        return $encryptedData;
    }
    /**
    *加密参数
    * @param $params string
    * @return string
    */
    public function encode($encryptStr)
    {
      $localIV = $this->iv;
      $encryptKey = $this->encryptKey;

      //Open module
      $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');

      //print "module = $module <br/>" ;

      mcrypt_generic_init($module, $encryptKey, $localIV);

      //Padding
//      $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
//
//      $pad = $block - (strlen($encryptStr) % $block); //Compute how many characters need to pad
//      $encryptStr .= str_repeat(chr(7), $pad); // After pad, the str length must be equal to block or its integer multiples

        $encryptStr = $this->addPKCS7Padding($encryptStr);

      //encrypt
      $encrypted = mcrypt_generic($module, $encryptStr);

      //Close
      mcrypt_generic_deinit($module);
      mcrypt_module_close($module);

      return base64_encode($encrypted);
    }

    private function  addPKCS7Padding($source)
    {
        $source = trim($source);
        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
        $pad = $block - (strlen($source) % $block);
        if ($pad <= $block) {
            $char = chr($pad);
            $source .= str_repeat($char, $pad);
        }
        return $source;
    }

    /**
     * 移去填充算法
     * @param string $source
     * @return string
     */
//    private function stripPKSC7Padding($source){
//        $source = trim($source);
//        $char = substr($source, -1);
//        $num = ord($char);
//        if($num==62)return $source;
//        $source = substr($source,0,-$num);
//        return $source;
//    }

    private function stripPKSC7Padding($str) {
        $block=mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,'cbc');
        $char=substr($str,-1,1);
        $num=ord($char);
        if($num>8) {
            return $str;
        }
        $len=strlen($str);
        for($i=$len-1;$i>=$len-$num;$i--) {
            if(ord(substr($str,$i,1))!=$num) {
                return $str;
            }
        }
        $str=substr($str,0,-$num);
        return $str;
    }

    /**
    *生成签名
    *@param  $app_key,$timestamp,$params   string
    *@return string
    */

    public function createSign($app_key,$timestamp,$params)
    {
        //生成签名
        $_sign = md5(trim($app_key.$timestamp.$params));
        return $_sign;
    }

    //校验签名

    /**
     * @param $app_key
     * @param $timestamp
     * @param $params
     * @param $sign
     * @return bool
     */
    public function verify($app_key,$timestamp,$params,$sign)
    {
        //1.生成签名
        $_sign = $this->createSign($app_key,$timestamp,$params);
        //2.签名校验
        Log::write($app_key);
        Log::write($timestamp);
        Log::write($params);
        if(strcasecmp($_sign,$sign) != 0)
        {
          return false;
        }
          return true;
    }
}
